﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Ext.h".
//-------------------------------------------------------------------

#include "CLMemory.h"

namespace UX_STL
{
namespace CLShell
{
	
//---------------------------- CLMemory ---------------------------//
/*
=================================================
	конструктор
=================================================
*/
	CLMemory::CLMemory():
		CLBaseObject(), _pID(null)
	{
	}
	
/*
=================================================
	деструктор
=================================================
*/
	CLMemory::~CLMemory()
	{
	}
	
/*
=================================================
	удалить буфер
=================================================
*/
	void CLMemory::Destroy()
	{
		_ReleaseRef();
		_pID = null;
	}
		
/*
=================================================
	закрывает буфер для чтения и/или записи
=================================================
*/
	bool CLMemory::EnqueueUnmap(CLQueue *pQueue, void *pPtr, const clevent_uni_array &aEvents, CLEvent **pEvent)
	{
		CHECK_ERR( pQueue != null and pPtr != null );

		cl_int		i_cl_err = 0;
		cl_event	p_event  = null;

		CL_CALL_R( i_cl_err = clEnqueueUnmapMemObject(	pQueue->Id(), _pID, pPtr,
														(cl_uint) aEvents.Count(), aEvents.raw_ptr(),
														pEvent != null ? &p_event : null ) );

		if ( p_event != null ) {
			*pEvent = new CLEvent( p_event );
		}
		return true;
	}
	
/*
=================================================
	возвращает информацию об объекте OpenGL,
	использованного для создания OpenCL объекта
=================================================
*/
OPENGL_ONLY(
	bool CLMemory::GetGLObject(cl_gl_object::type &eType, GLuint &uIdent)
	{
		CHECK_ERR( _pID != null );

		cl_int	i_cl_err = 0;

		CL_CALL_R( i_cl_err = clGetGLObjectInfo( _pID, (cl_gl_object_type *)&eType, &uIdent ) );
		return true;
	}
)

	__UX_CL_RC_IMPL( CLMemory, _pID, MemObject, MEM )



//---------------------------- CLBuffer ---------------------------//
/*
=================================================
	конструктор
=================================================
*/
	CLBuffer::CLBuffer(): CLMemory()
	{
	}

/*
=================================================
	деструктор
=================================================
*/
	CLBuffer::~CLBuffer()
	{
	}
		
/*
=================================================
	создать буфер
=================================================
*/
	bool CLBuffer::Create(usize uSize, cl_memory::type eFlags, void *pBuf)
	{
		CHECK_ERR( uSize != 0 );

		Destroy();

		cl_int	i_cl_err = 0;
		CL_CALL_R( _pID = clCreateBuffer( CLDEVICE()->Context(), eFlags, (size_t)uSize, pBuf, &i_cl_err ) );

		return true;
	}
	
/*
=================================================
	создать буфер
=================================================
*/
OPENGL_ONLY(
	bool CLBuffer::Create(const GLShell::GLBuffer *pBuffer, cl_memory::type eFlags)
	{
		CHECK_ERR( pBuffer != null );

		Destroy();

		cl_int	i_cl_err = 0;
		CL_CALL_R( _pID = clCreateFromGLBuffer( CLDEVICE()->Context(), eFlags, pBuffer->Id(), &i_cl_err ) );

		return true;
	}
)

/*
=================================================
	добавляет команду чтения
=================================================
*/
	bool CLBuffer::EnqueueRead(CLQueue *pQueue, bool bASync, usize uOffset, usize uDataSize, void *pData,
								const clevent_uni_array &aEvents, CLEvent **pEvent)
	{
		CHECK_ERR( pQueue != null and pData != null );

		cl_int		i_cl_err = 0;
		cl_event	p_event  = null;

		CL_CALL_R( i_cl_err = clEnqueueReadBuffer( pQueue->Id(), _pID, bASync ? CL_FALSE : CL_TRUE,
													uOffset, uDataSize, pData, (cl_uint) aEvents.Count(),
													aEvents.raw_ptr(), pEvent != null ? &p_event : null ) );
		if ( p_event != null ) {
			*pEvent = new CLEvent( p_event );
		}
		return true;
	}

/*
=================================================
	добавляет команду чтения
=================================================
*/
	bool CLBuffer::EnqueueRead(CLQueue *pQueue, bool bASync, const svec3 &vBufOffset, const svec3 &vDataOffset,
								const svec3 &vDataSize, const svec2 &vBufRowSlicePitch,
								const svec2 &vDataRowSlicePitch, void *pData,
								const clevent_uni_array &aEvents, CLEvent **pEvent)
	{
		CHECK_ERR( pQueue != null and pData != null );
		
		cl_int		i_cl_err = 0;
		cl_event	p_event  = null;

		CL_CALL_R( i_cl_err = clEnqueueReadBufferRect( pQueue->Id(), _pID, bASync ? CL_FALSE : CL_TRUE,
														vBufOffset.ptr(), vDataOffset.ptr(), vDataSize.ptr(),
														vBufRowSlicePitch.x, vBufRowSlicePitch.y,
														vDataRowSlicePitch.x, vDataRowSlicePitch.y,
														pData, (cl_uint) aEvents.Count(), aEvents.raw_ptr(),
														pEvent != null ? &p_event : null ) );
		if ( p_event != null ) {
			*pEvent = new CLEvent( p_event );
		}
		return true;
	}

/*
=================================================
	добавляет команду записи
=================================================
*/
	bool CLBuffer::EnqueueWrite(CLQueue *pQueue, bool bASync, usize uOffset, usize uDataSize, const void *pData,
								const clevent_uni_array &aEvents, CLEvent **pEvent)
	{
		CHECK_ERR( pQueue != null and pData != null );

		cl_int		i_cl_err = 0;
		cl_event	p_event  = null;

		CL_CALL_R( i_cl_err = clEnqueueWriteBuffer( pQueue->Id(), _pID, bASync ? CL_FALSE : CL_TRUE,
													uOffset, uDataSize, pData, (cl_uint) aEvents.Count(),
													aEvents.raw_ptr(), pEvent != null ? &p_event : null ) );
		if ( p_event != null ) {
			*pEvent = new CLEvent( p_event );
		}
		return true;
	}
	
/*
=================================================
	добавляет команду записи
=================================================
*/
	bool CLBuffer::EnqueueWrite(CLQueue *pQueue, bool bASync, const svec3 &vBufOffset, const svec3 &vDataOffset,
								const svec3 &vDataSize, const svec2 &vBufRowSlicePitch,
								const svec2 &vDataRowSlicePitch, const void *pData,
								const clevent_uni_array &aEvents, CLEvent **pEvent)
	{
		CHECK_ERR( pQueue != null and pData != null );
		
		cl_int		i_cl_err = 0;
		cl_event	p_event  = null;

		CL_CALL_R( i_cl_err = clEnqueueWriteBufferRect( pQueue->Id(), _pID, bASync ? CL_FALSE : CL_TRUE,
														vBufOffset.ptr(), vDataOffset.ptr(), vDataSize.ptr(),
														vBufRowSlicePitch.x, vBufRowSlicePitch.y,
														vDataRowSlicePitch.x, vDataRowSlicePitch.y,
														pData, (cl_uint) aEvents.Count(), aEvents.ptr(),
														pEvent != null ? &p_event : null ) );
		if ( p_event != null ) {
			*pEvent = new CLEvent( p_event );
		}
		return true;
	}
	
/*
=================================================
	отображает буфер для чтения и/или записи
=================================================
*/
	bool CLBuffer::EnqueueMap(void *&pResult, CLQueue *pQueue, bool bASync, cl_map_flag::type eFlags, usize uOffset,
								usize uSize, const clevent_uni_array &aEvents, CLEvent **pEvent)
	{
		CHECK_ERR( pQueue != null );
		
		cl_int		i_cl_err = 0;
		cl_event	p_event  = null;

		CL_CALL_R( pResult = clEnqueueMapBuffer( pQueue->Id(), _pID, bASync ? CL_FALSE : CL_TRUE,
												 eFlags, uOffset, uSize, (cl_uint) aEvents.Count(),
												 aEvents.raw_ptr(), pEvent != null ? &p_event : null, &i_cl_err ) );
		if ( p_event != null ) {
			*pEvent = new CLEvent( p_event );
		}
		return true;
	}



//---------------------------- CLImage ----------------------------//
/*
=================================================
	конструктор
=================================================
*/
	CLImage::CLImage(): CLMemory()
	{
	}

/*
=================================================
	деструктор
=================================================
*/
	CLImage::~CLImage()
	{
	}
	
/*
=================================================
	перемещает данные
=================================================
*/
	void CLImage::SwapData (CLImage &image)
	{
		_swap( this->_pID,		image._pID );
		_swap( this->_sFormat,	image._sFormat );
		_swap( this->_vTexDim,	image._vTexDim );
	}

/*
=================================================
	создать текстуру
=================================================
*/
	bool CLImage::Create2D(const svec2 &vDim, cl_memory::type eFlags, const cl_img_format &sFormat, void *pImage, usize uRowPitch)
	{
		Destroy();
		
		cl_image_format		s_img_fmt;
		cl_int				i_cl_err = 0;

		s_img_fmt.image_channel_data_type	= sFormat.eChannel;
		s_img_fmt.image_channel_order		= sFormat.eOrder;

		CL_CALL_R( _pID = clCreateImage2D( CLDEVICE()->Context(), eFlags, &s_img_fmt,
												vDim.x, vDim.y, uRowPitch, pImage, &i_cl_err ) );
		_vTexDim = svec3( vDim.x, vDim.y, 0 );
		_sFormat = sFormat;

		return true;
	}
	
/*
=================================================
	создать текстуру
=================================================
*/
	bool CLImage::Create3D(const svec3 &vDim, cl_memory::type eFlags, const cl_img_format &sFormat, void *pImage, usize uRowPitch, usize uSlicePitch)
	{
		Destroy();
		
		cl_image_format		s_img_fmt;
		cl_int				i_cl_err = 0;
		
		s_img_fmt.image_channel_data_type	= sFormat.eChannel;
		s_img_fmt.image_channel_order		= sFormat.eOrder;

		CL_CALL_R( _pID = clCreateImage3D( CLDEVICE()->Context(), eFlags, &s_img_fmt, vDim.x, vDim.y, vDim.z,
											uRowPitch, uSlicePitch, pImage, &i_cl_err ) );

		_vTexDim	= vDim;
		_sFormat	= sFormat;
		return true;
	}
	

#ifdef _UXS_USE_OPENGL
/*
=================================================
	создать текстуру из OpenGL текстуры
=================================================
*/
	namespace gl_tex {
		using namespace GLShell::gl_texture;
	}

	namespace gl_face {
		using namespace GLShell::gl_cube_face;
	}

	bool CLImage::CreateFromTexture(const GLShell::GLTexture *pTexture, cl_memory::type eFlags, uint uMipMap, GLShell::gl_cube_face::type eFace)
	{
		CHECK_ERR( pTexture != null );

		Destroy();

		cl_int	i_cl_err = 0;
		GLenum	e_target = pTexture->Target();
		
		if ( e_target == gl_tex::TEXTURE_CUBE_MAP )
			e_target = (eFace != gl_face::_UNKNOWN ) ? eFace : gl_face::POSITIVE_X;

		CHECK_ERR( CreateFromTextureGL( e_target, pTexture->Id(), eFlags, uMipMap ) );

		_vTexDim	= pTexture->Dimension().To<svec3>();
		s_GLForamtToCLFormat( pTexture->InternalFormat(), _sFormat );

		return true;
	}
	
/*
=================================================
	создать текстуру из OpenGL RenderBuffer'а
=================================================
*/
	bool CLImage::CreateFromRenderbuffer(const GLShell::GLRenderBuffer *pRB, cl_memory::type eFlags)
	{
		CHECK_ERR( pRB != null );

		Destroy();

		cl_int	i_cl_err = 0;
		CL_CALL_R( _pID = clCreateFromGLRenderbuffer( CLDEVICE()->Context(), eFlags, pRB->Id(), &i_cl_err ) );
		
		_vTexDim	= pRB->Dimension().To<svec3>();
		s_GLForamtToCLFormat( pRB->InternalFormat(), _sFormat );

		return true;
	}
	
/*
=================================================
	создать текстуру из OpenGL текстуры
=================================================
*/
	bool CLImage::CreateFromTextureGL(GLenum eTarget, GLuint uID, cl_memory::type eFlags, uint uMipmap)
	{
		CHECK_ERR( uID != 0 );
		CHECK_ERR( CLDEVICE()->IsSharedWithOpenGL() );

		Destroy();

		cl_int	i_cl_err = 0;

		if ( eTarget == gl_tex::TEXTURE_2D or
			(eTarget >= gl_tex::_CUBEFACE_FIRST and eTarget <= gl_tex::_CUBEFACE_LAST) )
		{
			CL_CALL_R( _pID = clCreateFromGLTexture2D( CLDEVICE()->Context(), eFlags, eTarget,
														uMipmap, uID, &i_cl_err ) );
		}
		else
		if ( eTarget == gl_tex::TEXTURE_3D or eTarget == gl_tex::TEXTURE_2D_ARRAY )
		{
			CL_CALL_R( _pID = clCreateFromGLTexture3D( CLDEVICE()->Context(), eFlags, eTarget,
														uMipmap, uID, &i_cl_err ) );
		}
		else
			RETURN_ERR( "unsupported texture target!" );

		//_vTexDim	= pTexture->Dimension();
		// TODO: cl img format to gl tex format

		return true;
	}

#endif	// _UXS_USE_OPENGL


/*
=================================================
	удалить текстуру
=================================================
*/
	void CLImage::Destroy()
	{
		CLMemory::Destroy();
		_vTexDim  = svec3();
		_sFormat  = cl_img_format();
	}

/*
=================================================
	добавить команду на чтение из текстуры
=================================================
*/
	bool CLImage::EnqueueRead(CLQueue *pQueue, bool bASync, const svec3 &vOffset, const svec3 &vDataSize,
								const svec2 &vDataRowSlicePitch, void *pData,
								const clevent_uni_array &aEvents, CLEvent **pEvent)
	{
		CHECK_ERR( pQueue != null and pData != null );

		cl_int		i_cl_err = 0;
		cl_event	p_event  = null;

		CL_CALL_R( i_cl_err = clEnqueueReadImage( pQueue->Id(), _pID, bASync ? CL_FALSE : CL_TRUE,
												  vOffset.ptr(), vDataSize.ptr(),
												  vDataRowSlicePitch.x, vDataRowSlicePitch.y,
												  pData, (cl_uint) aEvents.Count(),
												  aEvents.raw_ptr(), pEvent != null ? &p_event : null ) );
		if ( p_event != null ) {
			*pEvent = new CLEvent( p_event );
		}
		return true;
	}

/*
=================================================
	добавить команду на запись в текстуру
=================================================
*/
	bool CLImage::EnqueueWrite(CLQueue *pQueue, bool bASync, const svec3 &vOffset, const svec3 &vDataSize,
								const svec2 &vDataRowSlicePitch, const void *pData,
								const clevent_uni_array &aEvents, CLEvent **pEvent)
	{
		CHECK_ERR( pQueue != null and pData != null );

		cl_int		i_cl_err = 0;
		cl_event	p_event  = null;

		CL_CALL_R( i_cl_err = clEnqueueWriteImage( pQueue->Id(), _pID, bASync ? CL_FALSE : CL_TRUE,
													vOffset.ptr(), vDataSize.ptr(),
													vDataRowSlicePitch.x, vDataRowSlicePitch.y,
													pData, (cl_uint) aEvents.Count(),
													aEvents.raw_ptr(), pEvent != null ? &p_event : null ) );
		if ( p_event != null ) {
			*pEvent = new CLEvent( p_event );
		}
		return true;
	}
	
/*
=================================================
	копировать изображение (pSrcImage) в
	текущее изображение (this)
=================================================
*/
	bool CLImage::EnqueueCopy(CLQueue *pQueue, CLImage *pSrcImage, const svec3 &vSrcOffset,
								const svec3 &vDstOffset, const svec3 &vSize,
								const clevent_uni_array &aEvents, CLEvent **pEvent)
	{
		CHECK_ERR( pQueue != null and pSrcImage != null );
		
		cl_int		i_cl_err = 0;
		cl_event	p_event = null;

		CL_CALL_R( i_cl_err = clEnqueueCopyImage( pQueue->Id(), pSrcImage->Id(), _pID,
												  vSrcOffset.ptr(), vDstOffset.ptr(), vSize.ptr(),
												  (cl_uint) aEvents.Count(), aEvents.raw_ptr(),
												  pEvent != null ? &p_event : null ) );
		if ( p_event != null ) {
			*pEvent = new CLEvent( p_event );
		}
		return true;
	}

/*
=================================================
	копировать буфер (pSrcBuf) в
	текущее изображение (this)
=================================================
*/
	bool CLImage::EnqueueCopy(CLQueue *pQueue, CLBuffer *pSrcBuf, usize uSrcOffset, const svec3 &vDstOffset,
								const svec3 &vSize, const clevent_uni_array &aEvents, CLEvent **pEvent)
	{
		CHECK_ERR( pQueue != null and pSrcBuf != null );
		
		cl_int		i_cl_err = 0;
		cl_event	p_event  = null;

		CL_CALL_R( i_cl_err = clEnqueueCopyBufferToImage( pQueue->Id(), pSrcBuf->Id(), _pID,
														  uSrcOffset, vDstOffset.ptr(), vSize.ptr(),
														  (cl_uint) aEvents.Count(), aEvents.raw_ptr(),
														  pEvent != null ? &p_event : null ) );
		if ( p_event != null ) {
			*pEvent = new CLEvent( p_event );
		}
		return true;
	}
	
/*
=================================================
	копировать текущее изображение (this) в
	буфер (pDstBuf)
=================================================
*/
	bool CLImage::EnqueueCopyToBuffer(CLQueue *pQueue, CLBuffer *pDstBuf, const svec3 &vSrcOffset,
										const svec3 &vSize, usize uDstOffset, 
										const clevent_uni_array &aEvents, CLEvent **pEvent)
	{
		CHECK_ERR( pQueue != null and pDstBuf != null );
		
		cl_int		i_cl_err = 0;
		cl_event	p_event  = null;

		CL_CALL_R( i_cl_err = clEnqueueCopyImageToBuffer( pQueue->Id(), _pID, pDstBuf->Id(),
														  vSrcOffset.ptr(), vSize.ptr(), uDstOffset,
														  (cl_uint) aEvents.Count(), aEvents.raw_ptr(),
														  pEvent != null ? &p_event : null ) );
		if ( p_event != null ) {
			*pEvent = new CLEvent( p_event );
		}
		return true;
	}
	
/*
=================================================
	отображает изображение для чтения и/или записи
=================================================
*/
	bool CLImage::EnqueueMap(void *&pResult, svec2 &vRowSlicePitch, CLQueue *pQueue, bool bASync,
							cl_map_flag::type eFlags, const svec3 &vOffset, const svec3 &vSize, 
							const clevent_uni_array &aEvents, CLEvent **pEvent)
	{
		CHECK_ERR( pQueue != null );
		
		cl_int		i_cl_err = 0;
		cl_event	p_event  = null;

		CL_CALL_R( pResult = clEnqueueMapImage( pQueue->Id(), _pID, bASync ? CL_FALSE : CL_TRUE,
												eFlags, vOffset.ptr(), vSize.ptr(), &vRowSlicePitch.x,
												&vRowSlicePitch.y, (cl_uint) aEvents.Count(), aEvents.raw_ptr(),
												pEvent != null ? &p_event : null, &i_cl_err ) );
		if ( p_event != null ) {
			*pEvent = new CLEvent( p_event );
		}
		return true;
	}
	
#ifdef _UXS_USE_OPENGL
/*
=================================================
	s_GLForamtToCLFormat
=================================================
*/
	namespace gl_ifmt
	{
		using namespace GLShell::gl_tex_iformat;
	}

	bool CLImage::s_GLForamtToCLFormat (GLShell::gl_tex_iformat::type fmt, OUT cl_img_format &clFormat)
	{
		switch ( fmt )
		{
			case gl_ifmt::R8 :				clFormat = cl_img_format( cl_img_channel_order::R,		cl_img_channel::UNORM_INT8	);	return true;
			case gl_ifmt::R8I :				clFormat = cl_img_format( cl_img_channel_order::R,		cl_img_channel::SINT8		);	return true;
			case gl_ifmt::R8UI :			clFormat = cl_img_format( cl_img_channel_order::R,		cl_img_channel::UINT8		);	return true;
			case gl_ifmt::R8_SNORM :		clFormat = cl_img_format( cl_img_channel_order::R,		cl_img_channel::SNORM_INT8	);	return true;
				
			case gl_ifmt::RG8 :				clFormat = cl_img_format( cl_img_channel_order::RG,		cl_img_channel::UNORM_INT8	);	return true;
			case gl_ifmt::RG8I :			clFormat = cl_img_format( cl_img_channel_order::RG,		cl_img_channel::SINT8		);	return true;
			case gl_ifmt::RG8UI :			clFormat = cl_img_format( cl_img_channel_order::RG,		cl_img_channel::UINT8		);	return true;
			case gl_ifmt::RG8_SNORM :		clFormat = cl_img_format( cl_img_channel_order::RG,		cl_img_channel::SNORM_INT8	);	return true;
				
			case gl_ifmt::RGB8 :			clFormat = cl_img_format( cl_img_channel_order::RGB,	cl_img_channel::UNORM_INT8	);	return true;
			case gl_ifmt::RGB8I :			clFormat = cl_img_format( cl_img_channel_order::RGB,	cl_img_channel::SINT8		);	return true;
			case gl_ifmt::RGB8UI :			clFormat = cl_img_format( cl_img_channel_order::RGB,	cl_img_channel::UINT8		);	return true;
			case gl_ifmt::RGB8_SNORM :		clFormat = cl_img_format( cl_img_channel_order::RGB,	cl_img_channel::SNORM_INT8	);	return true;
					
			case gl_ifmt::RGBA8 :			clFormat = cl_img_format( cl_img_channel_order::RGBA,	cl_img_channel::UNORM_INT8	);	return true;
			case gl_ifmt::RGBA8I :			clFormat = cl_img_format( cl_img_channel_order::RGBA,	cl_img_channel::SINT8		);	return true;
			case gl_ifmt::RGBA8UI :			clFormat = cl_img_format( cl_img_channel_order::RGBA,	cl_img_channel::UINT8		);	return true;
			case gl_ifmt::RGBA8_SNORM :		clFormat = cl_img_format( cl_img_channel_order::RGBA,	cl_img_channel::SNORM_INT8	);	return true;
			
			case gl_ifmt::R16 :				clFormat = cl_img_format( cl_img_channel_order::R,		cl_img_channel::UNORM_INT16	);	return true;
			case gl_ifmt::R16I :			clFormat = cl_img_format( cl_img_channel_order::R,		cl_img_channel::SINT16		);	return true;
			case gl_ifmt::R16UI :			clFormat = cl_img_format( cl_img_channel_order::R,		cl_img_channel::UINT16		);	return true;
			case gl_ifmt::R16_SNORM :		clFormat = cl_img_format( cl_img_channel_order::R,		cl_img_channel::SNORM_INT16	);	return true;
				
			case gl_ifmt::RG16 :			clFormat = cl_img_format( cl_img_channel_order::RG,		cl_img_channel::UNORM_INT16	);	return true;
			case gl_ifmt::RG16I :			clFormat = cl_img_format( cl_img_channel_order::RG,		cl_img_channel::SINT16		);	return true;
			case gl_ifmt::RG16UI :			clFormat = cl_img_format( cl_img_channel_order::RG,		cl_img_channel::UINT16		);	return true;
			case gl_ifmt::RG16_SNORM :		clFormat = cl_img_format( cl_img_channel_order::RG,		cl_img_channel::SNORM_INT16	);	return true;
				
			case gl_ifmt::RGB16 :			clFormat = cl_img_format( cl_img_channel_order::RGB,	cl_img_channel::UNORM_INT16	);	return true;
			case gl_ifmt::RGB16I :			clFormat = cl_img_format( cl_img_channel_order::RGB,	cl_img_channel::SINT16		);	return true;
			case gl_ifmt::RGB16UI :			clFormat = cl_img_format( cl_img_channel_order::RGB,	cl_img_channel::UINT16		);	return true;
			case gl_ifmt::RGB16_SNORM :		clFormat = cl_img_format( cl_img_channel_order::RGB,	cl_img_channel::SNORM_INT16	);	return true;
					
			case gl_ifmt::RGBA16 :			clFormat = cl_img_format( cl_img_channel_order::RGBA,	cl_img_channel::UNORM_INT16	);	return true;
			case gl_ifmt::RGBA16I :			clFormat = cl_img_format( cl_img_channel_order::RGBA,	cl_img_channel::SINT16		);	return true;
			case gl_ifmt::RGBA16UI :		clFormat = cl_img_format( cl_img_channel_order::RGBA,	cl_img_channel::UINT16		);	return true;
			case gl_ifmt::RGBA16_SNORM :	clFormat = cl_img_format( cl_img_channel_order::RGBA,	cl_img_channel::SNORM_INT16	);	return true;
			
			case gl_ifmt::RGB5 :			clFormat = cl_img_format( cl_img_channel_order::RGB,	cl_img_channel::UNORM_SHORT_555	);	return true;
			case gl_ifmt::RGB10 :			clFormat = cl_img_format( cl_img_channel_order::RGB,	cl_img_channel::UNORM_INT_101010);	return true;
			
			case gl_ifmt::R32I :			clFormat = cl_img_format( cl_img_channel_order::R,		cl_img_channel::SINT32	);	return true;
			case gl_ifmt::RG32I :			clFormat = cl_img_format( cl_img_channel_order::RG,		cl_img_channel::SINT32	);	return true;
			case gl_ifmt::RGB32I :			clFormat = cl_img_format( cl_img_channel_order::RGB,	cl_img_channel::SINT32	);	return true;
			case gl_ifmt::RGBA32I :			clFormat = cl_img_format( cl_img_channel_order::RGBA,	cl_img_channel::SINT32	);	return true;
				
			case gl_ifmt::R32UI :			clFormat = cl_img_format( cl_img_channel_order::R,		cl_img_channel::UINT32	);	return true;
			case gl_ifmt::RG32UI :			clFormat = cl_img_format( cl_img_channel_order::RG,		cl_img_channel::UINT32	);	return true;
			case gl_ifmt::RGB32UI :			clFormat = cl_img_format( cl_img_channel_order::RGB,	cl_img_channel::UINT32	);	return true;
			case gl_ifmt::RGBA32UI :		clFormat = cl_img_format( cl_img_channel_order::RGBA,	cl_img_channel::UINT32	);	return true;
			
			case gl_ifmt::R16F :			clFormat = cl_img_format( cl_img_channel_order::R,		cl_img_channel::HALF	);	return true;
			case gl_ifmt::RG16F :			clFormat = cl_img_format( cl_img_channel_order::RG,		cl_img_channel::HALF	);	return true;
			case gl_ifmt::RGB16F :			clFormat = cl_img_format( cl_img_channel_order::RGB,	cl_img_channel::HALF	);	return true;
			case gl_ifmt::RGBA16F :			clFormat = cl_img_format( cl_img_channel_order::RGBA,	cl_img_channel::HALF	);	return true;
			
			case gl_ifmt::R32F :			clFormat = cl_img_format( cl_img_channel_order::R,		cl_img_channel::FLOAT	);	return true;
			case gl_ifmt::RG32F :			clFormat = cl_img_format( cl_img_channel_order::RG,		cl_img_channel::FLOAT	);	return true;
			case gl_ifmt::RGB32F :			clFormat = cl_img_format( cl_img_channel_order::RGB,	cl_img_channel::FLOAT	);	return true;
			case gl_ifmt::RGBA32F :			clFormat = cl_img_format( cl_img_channel_order::RGBA,	cl_img_channel::FLOAT	);	return true;
		}
		
		clFormat = cl_img_format();
		return false;
	}

#endif

//-------------------------------------------------------------------

}	// CLShell
}	// UX_STL